package com.hjm.framework.websocket;

import com.hjm.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.io.*;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName WebSocketThread
 * @Deacription TODO
 * @Author Administrator
 * @Version 1.0
 **/
@Slf4j
public class WebSocketThread extends Thread{

    private BufferedReader reader;   //读取数据的buffer
    private Session session;         //会话ID


    /**
     *每个连接的sesssion
     */
    private static Map<String, Session> sessionMap = new ConcurrentHashMap<String, Session>();
    /**
     *读取的数据长度
     */
    private static Map<String, Integer> lengthMap = new ConcurrentHashMap<String, Integer>();

    public WebSocketThread(InputStream in, Session session) throws FileNotFoundException {
        //this.reader = new BufferedReader(new InputStreamReader(in));
        //windows
        //this.reader = new BufferedReader(new FileReader(new File("D://tomcat/apache-tomcat-8.5.54/apache-tomcat-8.5.54/logs/catalina.2021-03-10.out")));
        this.reader = new BufferedReader(new InputStreamReader(in));
        this.session = session;
    }

    @Override
    public void run() {
        AtomicInteger countTimeout = new AtomicInteger(1);
        sessionMap.put(session.getId(), session);
        lengthMap.put(session.getId(), 1);//默认从第一行开始*/
        log.info("开始读取日志....................");
        boolean first = true;
        while (sessionMap.get(session.getId()) != null) {
            try {
                //日志文件路径，获取最新的
                //字符流
                Object[] lines = reader.lines().toArray();
                if (lines.length != 0) {
                    //只取从上次之后产生的日志
                    Object[] copyOfRange = Arrays.copyOfRange(lines, 0, lines.length);

                    //对日志进行着色，更加美观  PS：注意，这里要根据日志生成规则来操作
                    for (int i = 0; i < copyOfRange.length; i++) {
                        String line = (String) copyOfRange[i];
                        //先转义
                        line = line.replaceAll("&", "&amp;")
                                .replaceAll("<", "&lt;")
                                .replaceAll(">", "&gt;")
                                .replaceAll("\"", "&quot;");

                        //处理等级
                        line = line.replace("DEBUG", "<span style='color: blue;'>DEBUG</span>");
                        line = line.replace("INFO", "<span style='color: green;'>INFO</span>");
                        line = line.replace("WARN", "<span style='color: orange;'>WARN</span>");
                        line = line.replace("ERROR", "<span style='color: red;'>ERROR</span>");


                        copyOfRange[i] = line;
                    }

                    //存储最新一行开始
                    //lengthMap.put(session.getId(), lines.length);

                    //第一次如果太大，截取最新的200行就够了，避免传输的数据太大
                    if(first && copyOfRange.length > 200){
                        copyOfRange = Arrays.copyOfRange(copyOfRange, copyOfRange.length - 200, copyOfRange.length);
                        first = false;
                    }
                    String result = StringUtils.join(copyOfRange, "<br/>");
                    //发送
                    send(session, result);
                } else {
                    countTimeout.incrementAndGet();
                    if (countTimeout.get() == 600) {
                        session.close();
                        break;
                    }
                }
                //休眠一秒
                Thread.sleep(1000);
            } catch (Exception e) {
                //捕获但不处理
                e.printStackTrace();
            } finally {

            }
        }
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ignored) {
            }
        }

        log.info("任务结束");
    }



    /**
     * 封装一个send方法，发送消息到前端
     */
    private void send(Session session, String message) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
